
//插件代码的支持
// Ratyli: jquery rating plugin
// version 0.2.1
// https://github.com/peet86/Ratyli
// <span class="ratyli" data-rate="3" data-ratemax="5"></span>    
// (c) 2015 Peter Varga [info@vargapeter.com]
// released under the Apache 2.0 license
(function ($) {
    $.ratyli = function (el, options) {
        var base = this;
        base.$el = $(el);
        base.el = el;

        base.$el.data("ratyli", base);

        base.init = function () {
            // extend with parameters
            base.options = $.extend({}, $.ratyli.defaultOptions, options);

            // extend with html5 dataset
            base.options = $.extend({}, base.options, base.$el.data());

            // for the loop
            base.set(base.options.rate, true);

            // event listeners for rating signs
            base.$el.on("click", "> *", function (e) {
                if (!base.options.disable) {
                    var target = e.target;
                    if (target.tagName != "SPAN") target = target.parentNode;
                    base.options.onSignClick.call(base, target);
                    var val = $(target).prevAll().length + 1;
                    base.set(val);
                }
            });

            base.$el.on("mouseenter", "> *", function (e) {
                var target = e.target;
                if (target.tagName != "SPAN") target = target.parentNode;

                if (!base.options.disable) {
                    $(target).addClass("rate-active");
                    $(target).prevAll().addClass("rate-active");
                }
                base.options.onSignEnter.apply(null, [base.options.rate, target]);
            });

            base.$el.on("mouseleave", "> *", function (e) {
                var target = e.target;
                if (target.tagName != "SPAN") target = target.parentNode;

                if (!base.options.disable) {
                    $(target).removeClass("rate-active");
                    $(target).prevAll().removeClass("rate-active");
                }
                base.options.onSignLeave.apply(null, [base.options.rate, target]);
            });

        };

        base.set = function (val, init) {
            if (val < 0 || (val % 1 != 0) || val > base.options.ratemax) val = 0; // reset to 0.

            if (val == 1 && base.options.rate == 1 && base.options.unrateable == true && !init) {
                val = 0;
            }

            base.options.rate = val;

            // reset html
            base.$el.html("");

            // set data-rate
            if (base.options.rate != 0) base.$el.attr("data-rate", base.options.rate);

            // set data-ratemax
            base.$el.attr("data-ratemax", base.options.ratemax);


            // generate signs
            var i = 0;
            while (i < base.options.ratemax) {
                var tmp = "";
                if (i < base.options.rate) {
                    tmp = base.signTemplate("full");
                } else {
                    tmp = base.signTemplate("empty");
                }
                base.$el.append(tmp);
                i++;
            }

            // set rated
            if (!init && !base.options.disable) {
                base.$el.addClass("rated");
                base.$el.attr("data-rate", val);
            }

            //rated callack
            base.options.onRated.call(base, val, init);

            return base.options.rate;
        };


        base.signTemplate = function (type) {
            return "<span class='rate rate-" + type + "' style='cursor:" + base.options.cursor + ";'>" + base.options[type] + "</span>";
        };

        base.init();

    };

    $.ratyli.defaultOptions = {
        disable: false,
        unrateable: false,
        full: "★",
        empty: "☆",
        cursor: "default",
        rate: 0,
        ratemax: 5,
        onSignEnter: function () { },
        onSignLeave: function () { },
        onSignClick: function () { },
        onRated: function () { }
    };

    $.fn.ratyli = function (options) {
        return this.each(function () {
            (new $.ratyli(this, options));
        });
    };

})(jQuery);

var _classPath = "";

/**
 * 组合路径
 * @returns 
 */
function auto_path() {
    if (_classPath.indexOf("/") >= 0) {
        return _classPath;
    } else {
        return `/api/app/${_classPath}`;
    }
}

/**
 * 获取根路径 示例/api/app
 * @returns 
 */
function auto_root_path() {
    if (_classPath.indexOf("/") >= 0) {
        return _classPath.substring(0, _classPath.lastIndexOf("/"));
    } else {
        return "/api/app";
    }
}

/**
 * 为子页面调用使用，点击layer.open的确定按钮 子页面点击选择 即关闭页面
 */
function FuncClickSure() {

    $(".layui-layer-btn0").trigger('click');
    console.log(location.href, "trigger.click");
    // var lays = document.getElementsByClassName("layui-layer-shade");
    // if (lays) {
    //     for (var _lay of lays) {
    //         $(_lay).trigger('click');
    //     }
    // }
}

/**
 * 隐藏dialog下方的确定取消按钮条
 */
function FuncHiddenSureButtons() {
    // console.log('layer-btn hide ',location.href);
    $(".layui-layer-btn").hide();
    console.log(location.href, "FuncHiddenSureButtons");
}

/**
 * 
 * @param {*} path 
 * @returns 
 */
function autoUrl(path) {
    // 获取当前页面的协议、域名和路径
    const protocol = window.location.protocol;
    const host = window.location.host;
    const currentPath = window.location.pathname;
    const baseUrl = protocol + '//' + host;

    let fullUrl;
    if (path.startsWith('/')) {
        // 如果 path 是绝对路径，直接拼接协议和域名
        fullUrl = baseUrl + path;
    } else {
        // 如果 path 是相对路径，结合当前页面路径进行拼接
        const currentDir = currentPath.substring(0, currentPath.lastIndexOf('/'));
        fullUrl = baseUrl + currentDir + '/' + path;
    }

    // 处理多个 pasteform 文件夹路径
    const parts = fullUrl.split('/');
    const newParts = [];
    let pasteformFound = false;
    for (const part of parts) {
        if (part === 'pasteform') {
            if (!pasteformFound) {
                newParts.push(part);
                pasteformFound = true;
            }
        } else {
            newParts.push(part);
        }
    }
    fullUrl = newParts.join('/');

    return fullUrl;
}

// // 示例用法
// const path = '../../view.html';
// const fullUrl = getFullUrl(path);
// console.log(fullUrl);


/**
 * 打开一个窗口
 * @param {*} title 
 * @param {*} url 
 * @param {*} _w 设定的宽度，可以不设置，默认为90%，可以设置为xxxpx
 * @param {*} _h 设定的高度，可以不设置，默认为90%,可以设置为xxxpx
 */
function open_window(title, url, _w, _h) {

    //这里做一个兼容处理
    // var _path = handlerPasteFormPath();
    // if (url.indexOf("path")>=0 && (url.indexOf("./view.html") == 0 || url.indexOf("./index.html")==0)) {
    //     url = _path + url.substring(2);
    // }
    if (url.indexOf('pasteform') >= 0) {
        url = autoUrl(url);
    }

    if (!_w) {
        _w = '1000px';
    }
    if (!_h) {
        _h = '800px';
    }
    var _th = '100%';
    var _tw = '100%';

    if (_w) {
        var _max_height = $(window).width();
        if (_w.indexOf('px') >= 0) {
            var _current_w = Number(_w.replace('px', ''));
            if (_current_w < _max_height) {
                _tw = _w;
            }
        }
        if (_w.indexOf("%") > 0) {
            _tw = _w;
        }
    }
    if (_h) {
        var _max_height = $(window).height();
        if (_h.indexOf('px') >= 0) {
            var _current_h = Number(_h.replace('px', ''));
            if (_current_h < _max_height) {
                _th = _h;
            }
        }
        if (_h.indexOf("%") > 0) {
            _th = _h;
        }
    }
    window.top.layer.open({
        type: 2,
        area: [_tw, _th],
        fix: false, //不固定
        maxmin: true,
        resize: true,
        shadeClose: true,
        shade: 0.8,
        title: title,
        content: url,
        success: function (layero, index) {
        }
    });
}

/**
 * 打开一个对话框,并等待选择结果
 * @param {*} _title 
 * @param {*} _url 
 * @param {*} _w 
 * @param {*} _h 
 * @param {*} callback 
 */
function open_select(_title, _url, _w, _h, callback) {

    //解析linkquery特性
    // var _linkquery = handlerBuildLinkQueryUrl();
    // if(_linkquery){
    //     if(_url.indexOf("?")>=0){
    //         _url = _url+_linkquery;
    //     }else{
    //         _url = '?'+_linkquery.substring(1);
    //     }
    // }
    //补充linkquery
    _url = handlerAutoQueryIncludeLinkQuery(_url);
    //补充表单{{:=item.xxx}}动态参数
    _url = handlerBuildDynamicUrl(_url);

    if (!_w) {
        _w = '80%';
    }
    if (!_h) {
        _h = '90%';
    }
    var _th = '100%';
    var _tw = '100%';

    if (_w) {
        var _max_height = $(window).width();
        if (_w.indexOf('px') >= 0) {
            var _current_w = Number(_w.replace('px', ''));
            if (_current_w < _max_height) {
                _tw = _w;
            }
        }
        if (_w.indexOf("%") > 0) {
            _tw = _w;
        }
    }
    if (_h) {
        var _max_height = $(window).height();
        if (_h.indexOf('px') >= 0) {
            var _current_h = Number(_h.replace('px', ''));
            if (_current_h < _max_height) {
                _th = _h;
            }
        }
        if (_h.indexOf("%") > 0) {
            _th = _h;
        }
    }

    window.top.layer.open({
        type: 2,
        area: [_tw, _th],
        fixed: true,
        maxmin: false,
        resize: false,
        scrollbar: false,
        shade: 0.6,
        shadeClose: true,
        title: _title,
        content: _url,
        btn: ['确定', '取消'],
        success: function (layero, index) {
        },
        yes: function (index, layero) {
            // console.log('yes:', _url);
            var _select = $(layero).find("iframe")[0].contentWindow.SelectObject;
            window.top.layer.close(index);
            // console.log('selected:', _select);
            callback(_select);
        },
        end: function () {
            console.log('end:', _url);
        }
    });
}

/**
 * 子窗口穿透过来，重新计算高度
 * @param {*} _height 
 * @param {*} _index 
 */
function set_dialog_height(_height, _index) {
    var _max_height = $(window).height();
    if (_height < _max_height * 0.9) {
        $(`#layui-layer${_index}`).css('height', _height);
        $(`#layui-layer${_index}`).css('top', (_max_height - _height) / 2);
        $(`#layui-layer-iframe${_index}`).css('height', _height - 46);
    }
}

/**
 * 查找这个属性 _global_data_properties
 **/
function funcFindPropertry(_name) {
    if (_global_data_properties) {
        for (var one of _global_data_properties) {
            if (one.name == _name) {
                return one;
            }
        }
    }
    return null;
}

/**
 * 查找同级的另外一个字段，有可能有__ _global_data_properties
 * @param {*} _name 
 * @param {*} _from 
 * @returns 
 */
function funcFindExpendPropertry(_name, _from) {
    if (_global_data_properties) {
        var _new_name = false;
        if (_from) {
            if (_from.indexOf("__") > 0) {
                var _la = _from.lastIndexOf("__");
                var _head = _from.substring(0, _la);
                _new_name = _head + "__" + _name;
            }
        }
        for (var one of _global_data_properties) {
            if (one.name == _name || (_new_name && one.name == _new_name)) {
                return one;
            }
        }
    }
    return null;
}

/**
 * 从某一个字段中查找某一个属性
 * @param {*} attributes 
 * @param {*} _name 
 * @returns 
 */
function funcFindAttribute(attributes, _name) {
    if (attributes) {
        for (var one of attributes) {
            if (one.name == _name) {
                return one;
            }
        }
    }
    return null;
}

/**
 * 打开一个表的列表，然后进行选择！
 * @param {*} _title 
 * @param {*} _className 
 * @param {*} num 
 * @param {*} callback 
 */
function funcOuterOpenSelect(_title, _className, num, callback) {
    var _url = _className;
    if (_url.indexOf('/') == -1) {
        _url = `${handlerPasteFormPath()}index.html?model=select&path=${_className}`;

    } else {
        _url = handlerBuildDynamicUrl(_className);
    }
    open_select(_title, _url + '&pf_num=' + num, "", "", callback);
}

/**
 * 获取pasteform的根目录 
 * 返回格式 /page/pasteform/
 * 也有可能是 比如/manage/pasteform/
 * 注意pasteform的框架的文件夹必须是这个名字才行！
 * 如果没有，则返回空
 */
function handlerPasteFormPath() {
    var _path = location.pathname;
    var _path_index = _path.indexOf("/pasteform/");
    if (_path_index >= 0) {
        return _path.substring(0, _path_index) + "/pasteform/";
    }
    return "";
}

/**
 * 打开对话框，基于sessionStorage存储读取对象信息并显示到表单中等待回传
 * @param {*} _title 
 * @param {*} _className 
 * @param {*} _session_key 
 * @param {*} callback 
 */
function funcObjectOpenSelect(_title, _className, _session_key, callback) {
    var _url = _className;
    if (_url.indexOf('/') == -1) {
        _url = `${handlerPasteFormPath()}view.html?model=object&path=${_className}&session_key=${_session_key}`;
    } else {
        _url = handlerBuildDynamicUrl(_className);
    }
    open_select(_title, _url, "", "", callback);
}

/**
* 注入时间区间 注意这个daterange库是改版过的，就是在库里面已经为这个输入框赋值了
* @param {*} elcid 
*/
function HandlerInitDateRange(elcid, _value) {
    var _start = '';
    var _end = '';
    if (_value) {
        var splits = _value.split(' ');
        _start = splits[0];
        var sizes = splits.length;
        _end = splits[sizes - 1];
    }
    if (typeof (pickerDateRange) != 'undefined') {
        if ($(`#${elcid}`).length > 0) {
            new pickerDateRange(elcid, {
                isTodayValid: true,
                defaultText: '  至  ',
                startDate: _start,
                endDate: _end,
                success: function (obj) { },
                clear: function () { }
            });
        } else {

        }
    } else {
        console.log('没有找到模块pickerDateRange 注入daterange失败！');
    }
}

// 判断字符串是否以.js结尾的函数，兼容旧浏览器
function isJsFile(str, suffix) {
    // const suffix = '.js';
    return str.slice(-suffix.length) === suffix;
}

/**
 * 载入js或者css等
 * @param {*} src 
 * @param {*} func 
 */
function loadLibFile(src, func) {
    if (src) {
        if (isJsFile(src, ".js")) {
            const script = document.createElement('script');
            script.src = src;
            script.onload = () => {
                if (func) {
                    const functionToExecute = window[func];
                    // 检查函数是否存在且为函数类型
                    if (typeof functionToExecute === 'function') {
                        // 执行函数
                        functionToExecute();
                    } else {
                        console.error(`名为 ${func} 的函数不存在或者不是一个有效的函数。`);
                    }
                }
            };
            script.onerror = () => {
                console.error(`Failed to load script: ${src}`);
            };
            document.head.appendChild(script);
        }
        if (isJsFile(src, ".css")) {
            const link = document.createElement('link');
            link.rel = 'stylesheet';
            link.href = src;
            link.onload = () => {
                if (func) {
                    const functionToExecute = window[func];
                    // 检查函数是否存在且为函数类型
                    if (typeof functionToExecute === 'function') {
                        // 执行函数
                        functionToExecute();
                    } else {
                        console.error(`名为 ${func} 的函数不存在或者不是一个有效的函数。`);
                    }
                }
            };
            link.onerror = () => {
                console.error(`Failed to load CSS: ${src}`);
            };
            document.head.appendChild(link);
        }
    }
}

/**
 * 获取范围内的随机值
 * @param {*} n 
 * @param {*} m 
 */
function randomValue(n, m) {
    return Math.floor(Math.random() * (m - n + 1)) + n;
}

//组列表
var _ui_data_list = new Array();

var BtnExpend = null;
/**
 * 缓存，哪些changeui特性
 */
var _changeui_list = new Array();//attribute val
/**
* 读取数据的模型 处理数据的模型
* @param {*} properties 
*/
async function LoadModelProperity(properties) {


    //加载query如果有
    LoadQuery(properties);

    handlerExchangeDataTypeToUIType(properties);

    //如果要加载markdown
    if (_global_need_loadmarkdown) {



        await new Promise((resolve, reject) => {
            var _script = document.createElement("script");
            _script.src = "../lib/editor.md/editormd.min.js";
            _script.type = "text/javascript";
            _script.onload = function () {
                resolve();
            }
            _script.onerror = function () {
                reject();
            }
            document.head.appendChild(_script);
        });
        //../lib/editor.md/css/editormd.min.css
        const _style = document.createElement('link');
        _style.type = 'text/css';
        _style.rel = "stylesheet";
        _style.href = "../lib/editor.md/css/editormd.min.css";
        document.head.appendChild(_style);

        var _paste = document.createElement("script");
        _paste.src = "../lib/editor.md/md.paste.js";
        _paste.type = "text/javascript";
        document.head.appendChild(_paste);
    }
    //如果要加载富文本
    if (_global_need_loadrichhtml) {
        await new Promise((resolve, reject) => {
            var _script = document.createElement("script");
            _script.src = "../lib/wangeditor/wangEditor.min.js";
            _script.type = "text/javascript";
            _script.onload = function () {
                resolve();
            }
            _script.onerror = function () {
                reject();
            }
            document.head.appendChild(_script);
        });
        E = window.wangEditor;
    }

    //剔除hide的项目
    _global_data_properties = _global_data_properties.filter(item => !item.hide);

    //处理group模式
    for (var k = 0; k < properties.length; k++) {
        var item = properties[k];
        if (item.attributes) {
            var _group = funcFindAttribute(item.attributes, "group");
            if (_group) {
                handlerTakeGroupInfo(_group.args1, _ui_data_list, item);
            } else {
                _ui_data_list.push(item);
            }
        } else {
            _ui_data_list.push(item);
        }
    }

    //最上方的组描点
    var _ui_tabs = new Array();
    if (_ui_data_list && _ui_data_list.length > 0) {
        if (_ui_data_list[0].isgroup) {
            _ui_data_list.forEach(ia => {
                if (ia.isgroup) {
                    _ui_tabs.push(ia);
                }
            });
            $(".newform").css('padding-top', '0px');
        }
    }


    //handlerChangeUiAttribute
    //整理changeui的联动
    if (_changeui_list && _changeui_list.length > 0) {
        for (let change_item of _changeui_list) {
            handlerChangeUiAttribute(change_item.attribute, change_item.value, false);
        }
    }

    // console.log(_ui_data_list);

    //进行多级模板渲染！
    var _template_form = $("#template_form").html();
    var _template_item = $("#template_tr_item").html();
    var _tpl_form = template(_template_form);
    var _tpl_item = template(_template_item);

    //以下是新版本
    var _ahtml = _tpl_form({ list: _ui_data_list, templatetr: _tpl_item, config: _config, tabs: _ui_tabs });
    $(".paste-form-body").html(_ahtml);

    //以下是旧版本
    // var _template = $("#templatemodel").html();
    // var _ahtml = template(_template, { list: properties, config: _config });
    // $(".paste-form-body").html(_ahtml);

    setTimeout(function () {
        FormLoaded(properties);
        funcAppendInputLength();
        //计算高度，返回
        var _height = $(".newform").height() + 140 + 70;
        if (_has_outer) {
            //如果计算的高度小于600，表单中有outer则至少保证高度为600
            if (_height < 600) {
                _height = 600;
            }
        }
        var _index = parent.layer.getFrameIndex(window.name); //获取窗口索引
        if (window.parent.set_dialog_height) {
            window.parent.set_dialog_height(_height, _index);
        } else {
            console.log('没有在父级找到函数set_dialog_height');
        }

        /**
         * selects lselect
         */
        $(".ulitems").on('click', 'li', function () {
            if ($(this).hasClass('selected')) {
                $(this).removeClass('selected');
            } else {
                $(this).addClass('selected');
            }
            var _name = $(this).parents(".ulitems").attr('name');
            if (_name) {
                var _pro = funcFindPropertry(_name);
                if (_pro) {
                    var _maxnum = 0;
                    var _attribute = funcFindAttribute(_pro.attributes, "selects");
                    if (_attribute) {
                        if (_attribute.args4) {
                            _maxnum = Number(_attribute.args4);
                        }
                    } else {
                        _attribute = funcFindAttribute(_pro.attributes, "lselect");
                        if (_attribute) {
                            if (_attribute.args4) {
                                _maxnum = Number(_attribute.args4);
                            }
                        }
                    }
                    if (_maxnum > 0) {
                        var _selnum = $(this).parents(".ulitems").find(".selected").length;
                        if (_selnum > _maxnum) {
                            $(this).siblings().removeClass('selected');
                            if (_maxnum > 1) {
                                layer.msg(`限定最多选择${_maxnum}项`);
                            }
                        }
                        if (_maxnum == 1) {
                            var _val = $(this).attr('value');
                            handlerReloadReplace(_pro.attributes, _name, _val);
                            handlerChangeUi(_pro.attributes, _val);
                            // var _attribute = funcFindAttribute(_pro.attributes, "reload");
                            // if (_attribute) {
                            //     var _val = $(this).attr('value');
                            //     if (_attribute.args1) {
                            //         _name = _attribute.args1;
                            //     }
                            //     handlerBuildNewUrlToLoad(_name, _val);
                            // }
                        }
                    }
                }
            }

        });
        // //分组的开关
        // $(".paste-form-body").on('click','.btngroup',function(){
        //     if($(this).hasClass("Hui-iconfont-arrow2-top")){
        //         $(this).removeClass("Hui-iconfont-arrow2-top").addClass("Hui-iconfont-arrow2-bottom");
        //         $(this).parents('.group').find('.gbody').addClass('close');//.hide();
        //     }else{
        //         $(this).removeClass("Hui-iconfont-arrow2-bottom").addClass("Hui-iconfont-arrow2-top");
        //         $(this).parents('.group').find('.gbody').removeClass("close");
        //     }
        // });
        registry_group_click_event();

    }, 100);

    if (location.search.indexOf("model=sunobj") == -1) {
        $(".paste-btn-submit").fadeIn();
    }
}

/**
 * 注册分组的点击事件
 */
function registry_group_click_event() {
    //分组的开关
    $(".paste-form-body").on('click', '.ghead', function () {
        var _current = $(this).find(".btngroup");
        if (_current) {
            if ($(_current).hasClass("Hui-iconfont-arrow2-top")) {
                $(_current).removeClass("Hui-iconfont-arrow2-top").addClass("Hui-iconfont-arrow2-bottom");
                $(_current).parents('.group').find('.gbody').addClass('close');//.hide();
            } else {
                $(_current).removeClass("Hui-iconfont-arrow2-bottom").addClass("Hui-iconfont-arrow2-top");
                $(_current).parents('.group').find('.gbody').removeClass("close");
            }
        }
    });
}

/**
 * 删除输入框的值
 * @param {*} elc 
 */
function handlerClean(elc) {
    var _parent = $(elc).parents('.formControls');
    if (_parent) {
        _parent.find('input,textarea').val('');
    }
}

/**
 * 加载表单的表的数据
 **/
function loadHeader(obj) {
    if (obj.title) {
        $(".form-header").find(".ititle").html(obj.title);
    }
    if (obj.desc) {
        $(".form-header").find(".idesc").html(obj.desc);
    }
    if (obj.attributes) {
        _global_class_attributes = obj.attributes;
        for (var _attribute of obj.attributes) {
            switch (_attribute.name) {
                case "button":
                    {
                        if (_attribute.args1) {
                            $(".paste-btn-submit").val(_attribute.args1);
                        }
                    }
                    break;
                case "loadlib":
                    {
                        //载入资源
                        loadLibFile(_attribute.args1, _attribute.args2);
                    }
                    break;
            }
        }
    }
    //_global_attributes = o.attributes;
}


/**
 * parseForm之后的表单数据处理，处理完成后就上传接口了，所以要做一些额外的校验等
 * 读取富文本的内容
 * 读取daterange的内容
 * @param {*} _info 
 */
function FuncHandlerParseFormValue(_info) {
    if (_global_data_properties != null) {
        for (var item of _global_data_properties) {
            switch (item.dataType) {
                case "richtext":
                    {
                        //注意id不一样
                        if ($('#' + item.name + 'editor').is(':visible')) {
                            if (item.editor) {
                                item.value = item.editor.txt.html();
                                _info[item.name] = item.value;
                                var _attribute = funcFindAttribute(item.attributes, "richtext");
                                if (_attribute) {
                                    if (_attribute.args2) {
                                        _info[_attribute.args2] = item.editor.txt.text();
                                    }
                                }
                            }
                        }
                    }
                    break;
                case "markdown":
                    {
                        //注意id不一样
                        if ($('#' + item.name + 'mdeditor').is(':visible')) {
                            if (item.editor) {
                                item.value = item.editor.getMarkdown();
                                _info[item.name] = item.value;
                                if (item.value) {
                                    var _attribute = funcFindAttribute(item.attributes, "markdown");
                                    if (_attribute) {
                                        if (_attribute.args2) {
                                            _info[_attribute.args2] = item.editor.getHTML();
                                        }
                                    }
                                }
                                delete _info[`${item.name}mdeditor-html-code`];
                                delete _info[`${item.name}mdeditor-markdown-doc`];
                            }
                        }
                    }
                    break;
                case "DateTime":
                case "Guid":
                    {
                        if (!item.required) {
                            if (_info[item.name] == '' || _info[item.name] == 'null') {
                                delete _info[item.name];
                            }
                        }
                    }
                    break;
                case "fentoyuan":
                    {
                        var _value = _info[item.name];
                        if (_value) {
                            _info[item.name] = Number(_value * 100);
                        }
                    }
                    break;
                case "score":
                    {
                        _info[item.name] = item.value;
                    }
                    break;
                case "daterange":
                    {
                        if (item.attributes) {
                            for (let _attribute of item.attributes) {
                                if (_attribute.name == 'daterange') {
                                    var _value = _info[item.name];//获取当前选中的值
                                    if (_value) {
                                        var splits = _value.split('  ');
                                        if (splits.length == 3) {
                                            let _start = `${splits[0]} 00:00:00`;
                                            let _end = `${splits[2]} 00:00:00`;
                                            if (_attribute.args1) {
                                                // _info[_attribute.args1] = _start;
                                                setValueToSameLevel(item.name, _info, _attribute.args1, _start);
                                            }
                                            if (_attribute.args2) {
                                                // _info[_attribute.args2] = _end;
                                                setValueToSameLevel(item.name, _info, _attribute.args2, _end);
                                            }

                                            if (_attribute.args4) {
                                                switch (_attribute.args4) {
                                                    case "times":
                                                        {
                                                            let _times = new Date(_start).getTime() / 1000;
                                                            let _timee = new Date(_end).getTime() / 1000;
                                                            // _info[_attribute.args1] = _times;
                                                            // _info[_attribute.args2] = _timee;
                                                            setValueToSameLevel(item.name, _info, _attribute.args1, _times);
                                                            setValueToSameLevel(item.name, _info, _attribute.args2, _timee);
                                                        }
                                                        break;
                                                    case "timems":
                                                        {
                                                            let _times = new Date(_start).getTime();
                                                            let _timee = new Date(_end).getTime();
                                                            // _info[_attribute.args1] = _times;
                                                            // _info[_attribute.args2] = _timee;
                                                            setValueToSameLevel(item.name, _info, _attribute.args1, _times);
                                                            setValueToSameLevel(item.name, _info, _attribute.args2, _timee);
                                                        }
                                                        break;
                                                }
                                            }
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    break;
                case "outers":
                    {
                        var _dataFrom = item.dataFrom;
                        var elc = `.outers${item.name}`;
                        var lis = $(elc).find('li');
                        var _ids = new Array();
                        if (lis.length > 0) {
                            for (var k = 0; k < lis.length; k++) {
                                var ii = lis[k];
                                if (_dataFrom == 'Int32[]' || _dataFrom == 'Int64[]') {
                                    _ids.push(Number($(ii).attr('dataid')));
                                } else {
                                    _ids.push($(ii).attr('dataid'));
                                }
                            }
                            if (_dataFrom.indexOf("[]") > 0) {
                                _info[item.name] = _ids;
                            } else {
                                _info[item.name] = _ids.toString();
                            }

                        }
                    }
                    break;
                case "selects":
                case "lselect":
                    {
                        //基于结果进行值拼接！
                        var _elcs = $(`[name=${item.name}]`).find('.selected');
                        if (_elcs && _elcs.length > 0) {
                            var _array = new Array();
                            for (var k = 0; k < _elcs.length; k++) {
                                _array.push($(_elcs[k]).attr('value'));
                            }
                            if (item.dataFrom.indexOf("[]") >= 0) {
                                if (item.dataFrom == "Int32[]" || item.dataFrom == "Int64[]" || item.dataFrom == "number[]") {
                                    var _newarray = new Array();
                                    _array.forEach(_ary => {
                                        _newarray.push(Number(_ary));
                                    });
                                    _info[item.name] = _newarray;
                                } else {
                                    _info[item.name] = _array;
                                    //如果是enum[] 不一定是string
                                }
                            } else {
                                //string
                                var _splitchar = ',';
                                if (item.attributes) {
                                    for (var _attribute of item.attributes) {
                                        if (_attribute.name == item.dataType) {
                                            if (_attribute.args2) {
                                                _splitchar = _attribute.args2;
                                            }
                                            break;
                                        }
                                    }
                                }
                                _info[item.name] = _array.join(_splitchar);
                            }
                        }
                    }
                    break;
                case "image":
                    {
                        //这里处理图片
                        if (item.num > 1) {
                            var _read = handlerReadImages(item.name);
                            if (_read) {
                                if (item.dataFrom == "String[]") {
                                    _info[item.name] = _read.split(',');
                                } else {
                                    _info[item.name] = _read;
                                }
                            } else {
                                delete _info[item.name];
                            }
                        } else {
                            if (_info[item.name] == 'null') {
                                delete _info[item.name];
                            }
                        }
                    }
                    break;
                case "object":
                    {
                        // if (item.dataFrom == "Object") {
                        if (_map_values.has(item.name)) {
                            _info[item.name] = _map_values.get(item.name);
                        } else {
                            delete _info[item.name];
                        }
                        // }
                    }
                    break;
                case "objects":
                    {
                        if (_map_values.has(item.name)) {
                            _info[item.name] = _map_values.get(item.name);
                        } else {
                            delete _info[item.name];
                        }
                    }
                    break;
                case "splitarray":
                    {
                        var _split_char = ',';//默认值使用逗号隔开
                        var _split = funcFindAttribute(item.attributes, "splitarray");
                        if (_split) {
                            if (_split.args1) {
                                _split_char = _split.args1;
                            }
                        }
                        if (_info.hasOwnProperty(item.name)) {
                            var _val = _info[item.name];
                            if (_val) {
                                _val = _val.replace(/，/g, _split_char);
                                if (item.dataFrom == "Int32[]" || item.dataFrom == "Int64[]") {
                                    var strs = _val.split(_split_char);
                                    var arr = new Array();
                                    for (var ia of strs) {
                                        arr.push(Number(ia));
                                    }
                                    _info[item.name] = arr;
                                } else {
                                    _info[item.name] = _val.split(_split_char);
                                }
                            } else {
                                delete _info[item.name];
                            }

                        }
                    }
                    break;
                case "cover":
                    {
                        let _img = $(".coverts .active");
                        if (_img) {
                            item.value = _img.attr("src");
                            _info[item.name] = item.value;
                        }
                        // var imgs = $(".coverts").find("img");
                        // if (imgs.length > 0) {
                        //     var _imgs = new Array();
                        //     for (var i = 0; i < imgs.length; i++) {
                        //         _imgs.push(imgs[i].attr("src"));
                        //     }
                        //     item.value = _imgs;
                        //     var _attribute = funcFindAttribute(item.attributes, "cover");
                        //     if (_attribute) {
                        //         if (_attribute.args2) {
                        //             _info[_attribute.args2] = _imgs[0];
                        //         }
                        //     }
                        // }
                    }
                    break;
                case "sunform":
                    {
                        var _id = "frame_" + item.name;
                        var _frame = document.getElementById(_id);
                        if (_frame) {
                            var _con = _frame.contentWindow;
                            if (_con) {
                                if (typeof _con.funcSubmitForm === 'function') {
                                    var _read = _con.funcSubmitForm();
                                    if (!_read) {
                                        return;
                                    } else {
                                        _info[item.name] = _read;
                                    }
                                }
                            }
                        }
                    }
                    break;
                case "datetime":
                    {
                        var _value = null;
                        if (_info.hasOwnProperty(item.name)) {
                            _value = _info[item.name];
                        }
                        var _attribute = funcFindAttribute(item.attributes, "datetime");
                        if (_attribute) {
                            if (_attribute.args2) {
                                switch (_attribute.args2) {
                                    case "times":
                                        {
                                            if (_value) {
                                                //_value要转换成完整的数据格式！
                                                var _time = new Date(_value).getTime();
                                                _info[item.name] = _time / 1000;
                                            }
                                        }
                                        break;
                                    case "timems":
                                        {
                                            if (_value) {
                                                var _time = new Date(_value).getTime();
                                                _info[item.name] = _time;
                                            }
                                        }
                                        break;
                                    default:
                                        {
                                            if (_value) {
                                                var _time = new Date(_value).Format(_attribute.args2);
                                                _info[item.name] = _time;
                                            }
                                        }
                                        break;
                                }
                            }
                        }
                    }
                    break;
            }

            // switch (item.dataFrom) {
            //     case "DateTime":
            //     case "Guid":
            //         {
            //             if (!item.required) {
            //                 if (_info[item.name] == '' || _info[item.name] == 'null') {
            //                     delete _info[item.name];
            //                 }
            //             }
            //         }
            //         break;
            //     default:
            //         break;
            // }

            if (item.nullable) {
                var _value = null;
                if (_info.hasOwnProperty(item.name)) {
                    _value = _info[item.name];
                }
                if (!_value) {
                    delete _info[item.name];
                } else {
                    if (_value == 'null') {
                        delete _info[item.name];
                    }
                }
            }

            if (item.dataFrom == "Guid") {
                var _value = null;
                if (_info.hasOwnProperty(item.name)) {
                    _value = _info[item.name];
                }
                if (_value == 'null') {
                    _value = null;
                }
                if (!_value) {
                    delete _info[item.name];
                }
                if (!item.nullable) {
                    if (!_value) {
                        _info[item.name] = "00000000-0000-0000-0000-000000000000";
                    }
                }
            }

            //校验必填项目!!!
            if (item.attributes) {
                //部分非官方的required的校验
                var _required = funcFindAttribute(item.attributes, "required");
                if (_required) {
                    //这里好像有问题啊 如果是group展开收缩呢?
                    var _hidden = $(`[name=${item.name}]`).closest('.hidden');
                    if (!_hidden) {
                        if (!_info[item.name]) {
                            $(`[name=${item.name}]`).focus();
                            layer.tips(`数据 ${item.title} 必填，请重新填写`, `[name=${item.name}]`, { tipsMore: true }, 1);
                            return false;
                        }
                    }
                }
            }
        }
    }
    return true;
}

/**
 * 
 * @param {*} name 对比字段 示例age或者info__age 
 * @param {*} target_info 哪个对象
 * @param {*} target_name 给哪个字段赋值，实例name val
 * @param {*} target_value 给字段赋予哪个值
 */
function setValueToSameLevel(name, target_info, target_name, target_value) {
    if (name.indexOf("__") >= 0) {
        let _last = name.lastIndexOf("__");
        let _new_name = name.substring(0, _last) + '__' + target_name;
        target_info[_new_name] = target_value;
    } else {
        target_info[target_name] = target_value;
    }
}

// /**
//  * 支持参数化url
//  * @param {*} _url 
//  * @returns 
//  */
// function handlerBuildDynamicUrl(_url) {
//     // const _url = '/api/app/cateInfo?path=nameGo&pro_id={{:=item.project_id}}&cateid={{:=item.cate_id}}';
//     // 定义正则表达式
//     const regex = /{{:=item\.(\w+)}}/g;
//     let match;
//     let keys = new Array();
//     while ((match = regex.exec(_url)) !== null) {
//         keys.push({ key: match[1], val: match[0] });
//     }
//     if (keys && keys.length > 0) {
//         for (var item of keys) {
//             if (item.key) {
//                 var _property = funcFindPropertry(item.key);
//                 if (_property) {
//                     var _reg = new RegExp(item.val, 'g');
//                     _url = _url.replace(_reg, _property.value);
//                 }
//             }
//         }
//     }
//     return _url;
// }

/**
 * 支持参数化url
 * @param {*} _url 
 * @returns 
 */
function handlerBuildDynamicUrl(_url) {
    const regex = /{{:=item\.(\w+)}}/g;
    let match;
    let keys = [];
    const urlParts = _url.split('?');
    let baseUrl = urlParts[0];
    let queryString = urlParts[1] || '';

    // 使用正则表达式匹配所有符合条件的变量
    while ((match = regex.exec(_url)) !== null) {
        keys.push({ key: match[1], val: match[0] });
    }

    if (keys && keys.length > 0) {
        const queryParams = new URLSearchParams(queryString);

        for (const item of keys) {
            if (item.key) {
                const _property = funcFindPropertry(item.key);
                if (_property) {
                    // 替换URL中的变量
                    const _reg = new RegExp(item.val, 'g');
                    _url = _url.replace(_reg, _property.value);

                    // 同时更新queryParams对象
                    for (const [key, value] of queryParams.entries()) {
                        if (value.includes(item.val)) {
                            queryParams.set(key, value.replace(_reg, _property.value));
                        }
                    }
                } else {
                    // 如果没有找到属性值，移除包含该变量的参数
                    for (const [key, value] of queryParams.entries()) {
                        if (value.includes(item.val)) {
                            queryParams.delete(key);
                        }
                    }
                }
            }
        }

        // 重新构建URL
        const newQueryString = queryParams.toString();
        _url = baseUrl + (newQueryString ? `?${newQueryString}` : '');
    }

    return _url;
}

/**
 * 为输入框添加对长度显示的支持
 */
function funcAppendInputLength() {
    var inputarr = $(".newform").find("input[type=text],textarea,input[type=password]")
    for (let i = 0; i < inputarr.length; i++) {
        if ($(inputarr[i]).attr('maxlength')) {
            if ($(inputarr[i]).css("display") == 'none') {
                continue;
            }
            $(inputarr[i]).parent().css('position', 'relative')
            var str = `<span class="spanlen">${$(inputarr[i]).val().length}/${$(inputarr[i]).attr('maxlength')}</span>`
            $(inputarr[i]).after(str)
            $(inputarr[i]).on("input", function () {
                var numstr = $(this).val().length + '/' + $(this).attr('maxlength')
                $(this).siblings('.spanlen').text(numstr)
            })
        }
    }
}

/**
 * 基于递归方法，把一级数据拆分为多级,name中包含__的分拆一级，如果是__num__的分拆数组
 * @param {*} flattenedData 
 * @returns 
 */
function convertFlattenedToNested(flattenedData) {
    // 判断是否是数组格式（键名中包含数字索引）
    const isArrayFormat = Object.keys(flattenedData).some(key => /^\d+__/.test(key));
    if (isArrayFormat) {
        // 如果是数组格式，初始化结果为数组
        const result = [];
        for (const key in flattenedData) {
            if (flattenedData.hasOwnProperty(key)) {
                const value = flattenedData[key];
                const parts = key.split('__');
                // 递归构建嵌套结构
                buildNestedStructure(result, parts, value);
            }
        }
        //   const _result = result.filter((obj)=>{
        //     return Object.values(obj).length>0;
        //   });
        //   return result;
        return removeEmptyValues(result);
    } else {
        // 否则，初始化结果为对象
        const result = {};
        for (const key in flattenedData) {
            if (flattenedData.hasOwnProperty(key)) {
                const value = flattenedData[key];
                const parts = key.split('__');
                // 递归构建嵌套结构
                buildNestedStructure(result, parts, value);
            }
        }
        //   return result;
        return removeEmptyValues(result);
    }
}

/**
 * 递归去除空值
 * @param {*} obj 
 * @returns 
 */
function removeEmptyValues(obj) {
    if (Array.isArray(obj)) {
        // 如果是数组，递归处理每个元素
        return obj
            .map(item => removeEmptyValues(item)) // 递归处理每个元素
            .filter(item => item !== null && item !== undefined && item !== ''); // 过滤掉空值
    } else if (typeof obj === 'object' && obj !== null) {
        // 如果是对象，递归处理每个属性
        const result = {};
        for (const key in obj) {
            if (obj.hasOwnProperty(key)) {
                const value = removeEmptyValues(obj[key]); // 递归处理属性值
                // 如果值不是空值，则保留该属性
                if (value !== null && value !== undefined && value !== '') {
                    result[key] = value;
                }
            }
        }
        // 如果对象没有任何属性，返回 undefined（表示移除该对象）
        return Object.keys(result).length > 0 ? result : undefined;
    } else {
        // 如果是基本类型，直接返回
        return obj;
    }
}

/**
 * 递归赋值
 * @param {*} current 
 * @param {*} parts 
 * @param {*} value 
 * @returns 
 */
function buildNestedStructure(current, parts, value) {
    if (current) {
        const part = parts[0]; // 当前处理的键部分

        // 如果是最后一个部分，直接赋值
        if (parts.length === 1) {
            current[part] = value;
            return;
        }

        // 判断下一级是否是数组
        if (!isNaN(parts[1])) {
            const index = parseInt(parts[1]);

            // 如果当前部分不存在，创建一个新的数组
            if (!current[part]) {
                current[part] = [];
            }

            // 获取或创建数组元素
            while (current[part].length <= index) {
                current[part].push({});
            }

            // 递归处理剩余部分
            buildNestedStructure(current[part][index], parts.slice(2), value);
        } else {
            // 如果当前部分不存在，创建一个新的对象
            if (!current[part]) {
                current[part] = {};
            }

            // 递归处理剩余部分
            buildNestedStructure(current[part], parts.slice(1), value);
        }
    }
}


/**
 * 删除objects的某一项
 * @param {*} elc 
 */
function handlerRemoveObjectItem(elc) {
    var _li = $(elc).parents("li");
    var _name = _li.attr('dataname');
    var _id = _li.attr('dataid');
    var objs = _map_values.get(_name);
    if (objs) {
        var _porperty = funcFindPropertry(_name);
        if (_porperty) {
            for (var i = 0; i < objs.length; i++) {
                if (objs[i]["_id"].toString() == _id) {
                    objs.splice(i, 1);
                    break;
                }
            }
        }
    }
    _li.remove();
    return false;
}

/**
 * 使用outer选择外表的ID，和显示对应的友好名称 navigater的升级版
 * @param {*} elc 
 */
function handler_outer_value(elc) {
    var _name = $(elc).attr('dataname');
    if (_global_data_properties) {
        var find = funcFindPropertry(_name);
        if (find) {
            if (find.dataType == "outer") {
                var _attribute = funcFindAttribute(find.attributes, 'outer');
                if (_attribute) {
                    if (typeof funcLinkOuterOpenSelect == "function") {
                        funcLinkOuterOpenSelect(`选择${find.title}`, _attribute.args1, '1', (obj) => {
                            if (obj) {
                                $(elc).val(handlerColumnValue(obj, _attribute.args4));
                                $(elc).parent().find(`[name=${_name}]`).val(obj[_attribute.args3]);
                                find.value = obj[_attribute.args3];
                                //看看是否有后续动作
                                var _laterread = funcFindAttribute(find.attributes, "loaditem");
                                if (_laterread) {
                                    var _url = _laterread.args1;
                                    if (_url) {
                                        var _read_url = handlerBuildDynamicUrl(_url);
                                        _apiget(_read_url, true, (cc, oo) => {
                                            if (cc == 200) {
                                                handler_replace_item(oo);
                                            }
                                        });
                                    }
                                }
                            }
                        });
                    } else {
                        funcOuterOpenSelect(`选择${find.title}`, _attribute.args1, '1', (obj) => {
                            if (obj) {
                                $(elc).val(handlerColumnValue(obj, _attribute.args4));
                                $(elc).parent().find(`[name=${_name}]`).val(obj[_attribute.args3]);
                                find.value = obj[_attribute.args3];
                                //看看是否有后续动作
                                var _laterread = funcFindAttribute(find.attributes, "loaditem");
                                if (_laterread) {
                                    var _url = _laterread.args1;
                                    if (_url) {
                                        var _read_url = handlerBuildDynamicUrl(_url);
                                        _apiget(_read_url, true, (cc, oo) => {
                                            if (cc == 200) {
                                                handler_replace_item(oo);
                                            }
                                        });
                                    }
                                }
                            }
                        });
                    }
                }
            }
            if (find.dataType == "outers") {
                var _attribute = funcFindAttribute(find.attributes, 'outers');
                if (_attribute) {
                    if (typeof funcLinkOuterOpenSelect == "function") {
                        funcLinkOuterOpenSelect(`选择${find.title}`, _attribute.args1, '100', (objs) => {
                            handler_display_outers_toui(objs, _attribute, elc);
                        });
                    } else {
                        funcOuterOpenSelect(`选择${find.title}`, _attribute.args1, '100', (objs) => {
                            handler_display_outers_toui(objs, _attribute, elc);
                        });
                    }
                }
            }
        }
    }
}

/**
 * 显示外选择的内容到UI
 * @param {*} objs 
 * @param {*} _attribute 
 * @param {*} elc 
 */
function handler_display_outers_toui(objs, _attribute, elc) {
    if (!Array.isArray(objs)) {
        objs = [objs];
    } else {
        // $(elc).parents('.outers').find('.ulouter').empty();//如果数据要从多个页中获取，不能用这个
    }
    for (var obj of objs) {
        if (obj) {
            var _name = handlerColumnValue(obj, _attribute.args4);// (obj[_attribute.args4]);
            var _id = (obj[_attribute.args3]);
            //判断当前列表是否存在，不存在则新增
            var par = $(elc).parents('.outers').find(`[dataid="${_id}"]`);
            if (par.length == 0) {
                var _ul = $(elc).parents('.outers').find('.ulouter');
                if (_ul) {
                    _ul.append(`<li dataid="${_id}">${_name}<span class="outer_close" onclick="$(this).parents('li').remove();">x</span></li>`);
                }
            }
        }
    }
}

/**
 * 使用object的模式，进行外部表单的创建，一般用于创建的时候
 * 这里要做页面的map处理，回传的时候基于对象的类型是object格式 还是string格式
 * @param {*} elc 
 */
function handler_object_value(elc) {
    var _name = $(elc).attr('dataname');
    if (_global_data_properties) {
        var find = funcFindPropertry(_name);
        if (find) {
            var _attribute = funcFindAttribute(find.attributes, 'object');
            if (_attribute) {
                funcObjectOpenSelect(`选择${find.title}`, _attribute.args1, find.session_key || '', (obj) => {
                    if (obj) {
                        $(elc).val(handlerColumnValue(obj, _attribute.args4));
                        $(elc).parent().find(`[name=${_name}]`).val(obj[_attribute.args3]);
                        _map_values.set(_name, obj);
                    }
                });
            } else {
                _attribute = funcFindAttribute(find.attributes, 'objects');
                if (_attribute) {
                    funcObjectOpenSelect(`选择${find.title}`, _attribute.args1, find.session_key || '', (obj) => {
                        if (Array.isArray(obj)) {
                            // _map_values.delete(_name);
                            for (var _obj of obj) {
                                displayObjectsToUI(_obj, _name, find);
                            }
                        } else {
                            displayObjectsToUI(obj, _name, find);
                        }
                    });
                }
            }
        }
    }
}

/**
 * 显示Objects的数据到UI
 * @param {*} obj 
 * @param {*} _name 
 * @param {*} find 
 */
function displayObjectsToUI(obj, _name, find) {
    if (obj) {
        var objs = _map_values.get(_name);
        if (!objs) {
            objs = new Array();
        }
        var _find_index = -1;
        var _find_id = handlerColumnValue(obj, find.display_id);
        for (var k = 0; k < objs.length; k++) {
            if (_find_id == objs[k]._id) {
                _find_index = 0;
                break;
            }
        }
        if (_find_index == -1) {
            objs.push(obj);
        } else {
            objs[_find_index] = obj;
        }

        var _ihtml = '';
        objs.forEach(oitem => {
            var _display = handlerColumnValue(oitem, find.display_name);
            var _id = handlerColumnValue(oitem, find.display_id);
            oitem._display = _display;
            oitem._id = _id;
            _ihtml += `<li dataid="${_id}" dataname="${_name}" onclick="handlerEditObject(this);">${_display}<span class="outer_close" onclick="handlerRemoveObjectItem(this);">x</span></li>`;
        });
        $(`.outers${_name}`).html(_ihtml);
        _map_values.set(_name, objs);
    }
}

// /**
//  * 读取linkquery的参数以&xxx=yyy&zzz=www的形式
//  * @returns 
//  */
// function handlerBuildLinkQueryUrl() {
//     var _linkquery = "";
//     if (_global_class_attributes) {
//         _global_class_attributes.forEach(_attribute => {
//             if (_attribute.name == "linkquery") {
//                 if (_attribute.args1) {
//                     var _args = _attribute.args1.split(',');
//                     _args.forEach(arg => {
//                         var _argval = readQueryFromSearch(arg);
//                         if (_argval != null) {
//                             _linkquery += `&${arg}=${_argval}`;
//                         }
//                     });
//                 }
//             }
//         });
//     }
//     return _linkquery;
// }

// /**
//  * 从当前url中获取对应的参数
//  */
// function readQueryFromSearch(key) {
//     // 获取参数
//     var url = window.location.search;
//     // 正则筛选地址栏
//     var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
//     // 匹配目标参数
//     var result = url.substr(1).match(reg);
//     //返回参数值
//     return result ? decodeURIComponent(result[2]) : null;
// }

/**
 * 读取linkquery的参数以&xxx=yyy&zzz=www的形式
 * 25.04.13 适配array模式 注意Object的要自己实现，建议使用sessionStorage的方式
 * @returns {string} 构建好的linkquery字符串
 */
function handlerBuildLinkQueryUrl() {
    let linkquery = [];
    if (Array.isArray(_global_class_attributes)) {
        for (const attribute of _global_class_attributes) {
            if (attribute.name === "linkquery" && attribute.args1) {
                const args = attribute.args1.split(',');
                for (const arg of args) {
                    const argvals = readQueryFromSearch(arg);
                    if (argvals.length > 0) {
                        for (const argval of argvals) {
                            linkquery.push(`${arg}=${argval}`);
                        }
                    }
                }
            }
        }
    }
    return linkquery.length > 0 ? '&' + linkquery.join('&') : '';
}

/**
 * 从当前url中获取对应的参数
 * 25.04.13 适配array模式 注意Object的要自己实现，建议使用sessionStorage的方式
 * @param {string} key - 要获取的参数名
 * @returns {Array<string>} 参数值数组，如果未找到则返回空数组
 */
function readQueryFromSearch(key) {
    const url = window.location.search;
    const reg = new RegExp(`(^|&)${key}=([^&]*)(&|$)`, 'g');
    const results = [];
    let match;
    while ((match = reg.exec(url)) !== null) {
        results.push(decodeURIComponent(match[2]));
    }
    return results;
}



/**
 * 基于linkquery的模式，自动整理query
 * @param {*} url 
 * @returns 
 */
function handlerAutoQueryIncludeLinkQuery(url) {
    var _link = {};
    if (_global_class_attributes) {
        _global_class_attributes.forEach(_attribute => {
            if (_attribute.name == "linkquery") {
                if (_attribute.args1) {
                    var _args = _attribute.args1.split(',');
                    _args.forEach(arg => {
                        var _argval = _apigetquery(arg);
                        if (_argval != null) {
                            // _linkquery += `&${arg}=${_argval}`;
                            _link[arg] = _argval;
                        }
                    });
                }
            }
        });
    }
    return appendQueryParams(url, _link);
}

/**
 * 解析 URL 并追加参数（如果参数不存在）
 * @param {string} url - 原始 URL
 * @param {Object} queryMap - 包含需要追加的 query 键值对的对象
 * @returns {string} - 处理后的 URL
 */
function appendQueryParams(url, queryMap) {
    if (typeof url !== 'string' || !url) {
        return url;
    }

    if (!queryMap || typeof queryMap !== 'object' || Array.isArray(queryMap)) {
        return url;
    }

    // 解析 URL 的路径、参数和哈希部分
    const [baseUrl, hash] = url.split('#');
    const [path, queryString] = baseUrl.split('?');

    // 解析现有的查询参数
    const queryParams = new URLSearchParams(queryString || '');

    // 遍历 queryMap，如果参数不存在则追加
    for (const [key, value] of Object.entries(queryMap)) {
        if (value !== undefined && value !== null && !queryParams.has(key)) {
            queryParams.set(key, value);
        }
    }

    // 拼接处理后的 URL
    const newQueryString = queryParams.toString();
    const newUrl = newQueryString ? `${path}?${newQueryString}` : path;

    // 如果有哈希部分，重新追加
    return hash ? `${newUrl}#${hash}` : newUrl;
}


/**
 * 基于表达式获取对象数据，返回字符串的，用于objects的+字段
 * @param {*} find 
 * @param {*} columnstr 
 * @returns 
 */
function handlerColumnValue(find, columnstr) {
    if (columnstr.indexOf("+") > 0) {
        var _strs = columnstr.split('+');
        var _aval = '';
        _strs.forEach(ii => {
            if (find.hasOwnProperty(ii)) {
                _aval += find[ii];
            } else {
                _aval += ii;
            }
        });
        return _aval;
    }
    return find[columnstr];
}

/**
 * 编辑objects的单个内容
 * @param {*} elc 
 */
function handlerEditObject(elc) {
    var _li = $(elc);
    var _name = _li.attr('dataname');
    var _id = _li.attr('dataid');
    var objs = _map_values.get(_name);
    if (objs) {
        var _porperty = funcFindPropertry(_name);
        if (_porperty) {
            var _attribute = funcFindAttribute(_porperty.attributes, "objects");
            if (_attribute) {
                var _current = null;
                for (var i = 0; i < objs.length; i++) {
                    if (objs[i]["_id"].toString() == _id) {
                        _current = objs[i];
                        break;
                    }
                }
                let session_key = `${_porperty.name}_000`;
                if (_current) {
                    //查看object
                    sessionStorage.setItem(session_key, JSON.stringify(_current));
                    funcObjectOpenSelect(`编辑${_current[_porperty.display_name]}`, _attribute.args1, session_key || '', (obj) => {
                        displayObjectsToUI(obj, _name, _porperty);
                    });
                } else {
                    sessionStorage.removeItem(session_key);
                }
            }
        }
    }
}

/**
 * 加载来源参数内容 在form渲染前，所以影响的是Property的信息
 * v25.04.13
 * @param {*} properties 
 */
function LoadQuery(properties) {
    properties.forEach(item => {
        if (item.attributes) {
            item.attributes.forEach(_attribute => {
                if (_attribute.name == 'query') {
                    if (_attribute.args1) {
                        let _query_val = readQueryFromSearch(_attribute.args1);
                        if (_query_val.length > 0) {
                            //这里还要处理，比如splitarray的特性等... 
                            switch (item.dataType) {
                                case "Int32": case "UInt32": case "Int64": case "UInt64":
                                    {
                                        item.value = Number(_query_val[0]);
                                    }
                                    break;
                                case "Int32[]": case "UInt32[]": case "Int64[]": case "UInt64[]":
                                    {
                                        let _varray = new Array();
                                        for (let a of _query_val) {
                                            _varray.push(Number(a));
                                        }
                                        item.value = _varray;
                                    }
                                    break;
                                default:
                                    {
                                        if (item.dataType.indexOf("[]") >= 0) {
                                            item.value = _query_val;
                                        } else {
                                            item.value = _query_val[0];
                                        }
                                    }
                                    break;
                            }
                            //如果事objects 我只是想一会提交的时候一并提交呢???

                            if (_attribute.args2) {
                                item.hidden = true;
                            }
                        }
                        //以下是旧版本，不适配array的情况
                        // let _query_val = _apigetquery(_attribute.args1);
                        // if (_query_val != null && _query_val != undefined) {
                        //     var _typeof = typeof (item.value);
                        //     if (_typeof == 'number') {
                        //         item.value = Number(_query_val);
                        //     } else {
                        //         item.value = _query_val;
                        //     }
                        //     if (_attribute.args2) {
                        //         item.hidden = true;
                        //     }
                        // }
                    }
                }
            });
        }
    });
}

/**
 * 内容嵌入后，执行一些加载绑定等！ 
 **/
function FormLoaded(properties) {
    properties.forEach(item => {
        if (item.dataType == "daterange") {
            if (item.name) {
                HandlerInitDateRange(item.name, item.value);
            }
        }
        if (item.dataType == "richtext") {
            InitRichEditor(item);//可以有多个富文本 {{name}}editortoolbar {{name}}editorbody window.{{name}}editor
        }
        if (item.dataType == "markdown") {
            InitMarkDownEditor(item);
        }
        if (item.dataType == "score") {
            $(`.raty${item.name}`).ratyli({
                step: false,
                onRated: function (score) {
                    item.value = score;
                }
            });
        }
        // if (item.attributes) {
        //     item.attributes.forEach(_attribute => {
        //         if (_attribute.name == 'query') {
        //             if (_attribute.args1) {
        //                 var _query_val = _apigetquery(_attribute.args1);
        //                 if (_query_val != null && _query_val != undefined) {
        //                     $(`[name=${item.name}]`).val(_query_val);
        //                     if (_attribute.args2) {
        //                         $(`[name=${item.name}]`).parents(".row").hide();
        //                     }
        //                 }
        //             }
        //         }
        //     });
        // }
    });
}

/**
 * 点击删除图片
 * @param {*} elc 
 */
function handlerTapImage(elc) {
    if (!$(elc).hasClass("active")) {
        $(elc).addClass("active").siblings().removeClass("active");
    }
}


/**
 * 更新封面的图片的选择项
 */
function funcUpdateImages() {
    if ($(".coverts").length > 0) {
        let imgs = new Array();
        $('.paste-form-body img').each(function () {
            var src = $(this).attr('src');
            if (src != 'undefined' && src != undefined && src != null && src != '') {
                if (imgs.indexOf(src) == -1) {
                    imgs.push(src);
                }
            }
        });
        var _html = '';
        var _zindex = 0;
        for (let src of imgs) {
            if (_zindex == 0) {
                _html += `<img class="cover_img active" onclick="handlerTapImage(this);" src="${src}">`;
            } else {
                _html += `<img class="cover_img" onclick="handlerTapImage(this);" src="${src}">`;
            }
            _zindex++;
        }
        $(".coverts").html(_html);
    }
}

/**
 * 初始化Markdown编辑器
 * @param {*} item 
 */
function InitMarkDownEditor(item) {
    var _editor = `${item.name}mdeditor`;
    var _high = 600;
    var _upload_url = "/api/app/Upload/Markdown";
    var _attribute = funcFindAttribute(item.attributes, "markdown");
    if (_attribute) {
        if (_attribute.args1) {
            var _h = Number(_attribute.args1);
            if (_h) {
                _high = _h;
            }
        }
        //2给另外一个值了 比如richtext回传txt markdown回传 html
        if (_attribute.args3) {
            _upload_url = handlerBuildDynamicUrl(_attribute.args3);
        }
    }

    BtnExpend = editormd.BtnMenu;

    _mdEditor = editormd(_editor, {
        height: _high,
        saveHTMLToTextarea: true,
        imageUpload: true,
        imageFormats: ["jpeg", "jpg", "gif", "png", "bmp", "webp"],
        imageUploadURL: _upload_url,
        imageUploadHeaders: { token: readToken() },
        markdown: item.value || '',
        path: '../lib/editor.md/lib/',
        // 自定义工具栏图标
        toolbarIcons: function () {
            // 添加自定义图标到默认工具栏
            return editormd.toolbarModes.full.concat(["insertTime"]);
        },

        // 自定义图标样式（使用 Font Awesome）
        toolbarIconsClass: {
            insertTime: "fa-clock-o" // 时钟图标
        },

        // 自定义图标点击事件
        toolbarHandlers: {
            insertTime: function (cm, icon, cursor, selection) {
                // 获取当前时间
                const now = new Date();
                const timeString = now.toLocaleTimeString();

                // 插入时间到编辑器
                // this.insertText(`当前时间: ${timeString}`);

                // 在光标位置插入文本，选中文本会被替换
// cm.replaceSelection("插入的文本");

// 示例：插入时间戳
const time = new Date().toLocaleTimeString();
cm.replaceSelection(`⏰ ${time}`);

// global_load_netword_images

                // 可添加其他逻辑，如显示提示
                console.log("插入时间:", timeString);
            }
        }
    });

    if (typeof initPasteDragImg == 'function') {
        initPasteDragImg(_mdEditor);
    }
    item.editor = _mdEditor;
}

/**
 * 初始化富文本 注意看命名规则 ui的ID的规则，要相互，支持单个页面多个富文本
 * @param {*} item 
 */
function InitRichEditor(item) {
    //注意这里的命名规则需要和ui一致
    var _toolbar = `${item.name}editorbar`;
    var _editor = `${item.name}editor`;

    var _high = 600;
    var _upload_url = "/api/app/Upload/UpImage";
    var _attribute = funcFindAttribute(item.attributes, "richtext");
    if (_attribute) {
        if (_attribute.args1) {
            var _h = Number(_attribute.args1);
            if (_h) {
                _high = _h;
            }
        }
        //2给另外一个值了 比如richtext回传txt markdown回传 html
        if (_attribute.args3) {
            _upload_url = handlerBuildDynamicUrl(_attribute.args3);
        }
    }

    const editor = new E(`#${_toolbar}`, `#${_editor}`) // 传入两个元素
    // 默认情况下，显示所有菜单
    editor.config.menus = [
        'head',
        'bold',
        'fontSize',
        // 'fontName',
        'italic',
        'underline',
        // 'strikeThrough',
        'indent',
        'lineHeight',
        'foreColor',
        // 'backColor',
        'link',
        // 'list',
        'todo',
        'justify',
        'quote',
        // 'emoticon',
        'image',
        // 'video',
        'table',
        'code',
        'splitLine',
        'undo',
        'redo'
    ]
    editor.config.uploadImgServer = _upload_url
    editor.config.uploadImgMaxSize = 2 * 1024 * 1024 // 2M
    editor.config.uploadImgAccept = ['jpg', 'jpeg', 'png', 'gif', 'webp']
    editor.config.uploadImgMaxLength = 3 // 一次最多上传 5 个图片
    editor.config.uploadImgHeaders = { token: readToken() }//注意这里要按照实际情况处理 这里估计要搞成配置的

    editor.config.customUploadImg = (files, insert) => {
        const formData = new FormData();
        for (let i = 0; i < files.length; i++) {
            formData.append('file', files[i]);
        }
        fetch(`${auto_root_path()}/Upload/UpImage?type=rich&size=1920*0`, {
            method: 'POST',
            headers: {
                'token': readToken()
            },
            body: formData
        })
            .then(response => {
                console.log(response);
                return response.json();
            })
            .then(result => {
                console.log(result);
                if (result.errno == 0) {
                    var _url = result.data[0].url;
                    // 插入图片到编辑器
                    insert(_url);
                    // 可以在这里添加其他自定义逻辑
                    if (_imageList.indexOf(_url) == -1) {
                        _imageList.push(_url);
                        //如果有coverts，则执行渲染操作
                    }
                    // 例如，记录上传日志
                    console.log('图片上传成功:', _url);
                } else {
                    console.error('图片上传失败:', result);
                }
            })
            .catch(error => {
                console.error('图片上传出错:', error);
            });
    };


    if (item.placeholder) {
        editor.config.placeholder = item.placeholder;
    }
    editor.create();
    if (item.value) {
        editor.txt.html(item.value);
    }
    item.editor = editor;
}
/**
 * 点击删除某一个图片
 * @param {*} elc 
 */
function handlerRemoveImageItem(elc) {

    var _elcControlls = $(elc).parents(".formControls");

    var _name = $(_elcControlls).find("input[type=text]").attr('name');
    $(elc).parents("li").remove();
    handlerReadImages(_name);

    //判断数量，是否显示+按钮
    var _find = funcFindPropertry(_name);
    console.log(_find);
    if (_find != null) {
        if (_find.num > 1) {
            var _imageul = $(_elcControlls).find(".imageul");
            if ($(_imageul).find("li").length > _find.num) {
                $(_imageul).find("li").eq(0).hide();
            } else {
                $(_imageul).find("li").eq(0).show();
            }
        }
    }
}

/**
 * 读取多图模式的值 并给对应的输入框赋值，为了给后面的form读取值
 * @param {*} _name 
 */
function handlerReadImages(_name) {
    var _array = new Array();
    var pars = $(`[name=${_name}]`).parents(".formControls").find("img");
    for (var k = 0; k < pars.length; k++) {
        var _img = pars[k];
        var _img_src = ($(_img).attr('src'));
        _array.push(_img_src);
    }
    if (_array.length == 0) {
        $(`[name=${_name}]`).val('');
        return '';
    } else {
        $(`[name=${_name}]`).val(_array.join(','));
        return _array.join(',');
    }
}

/**
 * 上传非图片 比如文件等
 **/
function handlerUploadOnlyFile(elc) {
    var _url = `${auto_root_path()}/Upload/UpFile`;
    var _dataurl = $(elc).attr('dataurl');
    if (_dataurl) {
        _url = _dataurl;
    }
    var _type = $(elc).attr('datatype');
    if (_type) {
        _url = `${_url}${(_url.indexOf("?") >= 0 ? '&' : '?')}type=${_type}`;
    }
    var _name = $(elc).attr("id");
    var _num = 1;
    if (elc.files && elc.files.length > _num) {
        layer.msg(`选择的文件过多，至多选择${_num}个文件！`);
    }
    if (elc.files.length > 0) {
        var loadid = layer.load();
        var formData = new FormData();
        for (var k = 0; k < elc.files.length; k++) {
            formData.append(elc.files[k].name, elc.files[k]);
        }
        $.ajax({
            url: _url,
            type: 'post',
            contentType: false,
            processData: false,
            async: true,
            data: formData,
            headers: { "token": readToken() },
            success: function (obj) {
                layer.close(loadid);
                $(elc).parents(".formControls").find(`[name=${_name}]`).val(obj.data[0].url);
                elc.value = null;
            },
            error: function (res) {
                if (loadid != 0) {
                    layer.close(loadid);
                }
                elc.value = null;
                layer.msg(res.statusText, { icon: 'error', time: 3000 });
            }
        });
    } else {
        // layer.msg("请选择至少一个有效的文件！");readmemberToken
    }
}

/**
 * 处理图片的上传，这里最好限制下文件格式 这个要看实际需求 基于这个可以改造一个，上传文件的比如xlsx
 **/
function handlerUploadFile(elc) {
    var _size = $(elc).attr("datasize");
    var _type = $(elc).attr("datatype");
    var _num = $(elc).attr("datanum");
    var _name = $(elc).attr("id");
    // console.log(_num, _type, _size);
    if (!_num) {
        _num = 1;
    }
    if (elc.files && elc.files.length > _num) {
        layer.msg(`选择的文件过多，至多选择${_num}个文件！`);
    }
    if (elc.files.length > 0) {
        var loadid = layer.load();
        var formData = new FormData();
        for (var k = 0; k < elc.files.length; k++) {
            formData.append(elc.files[k].name, elc.files[k]);
        }
        $.ajax({
            url: `${auto_root_path()}/Upload/UpImage?type=${_type}&size=${_size}`,
            type: 'post',
            contentType: false,
            processData: false,
            async: true,
            data: formData,
            headers: { "token": readToken() },
            success: function (obj) {
                // console.log(obj);
                layer.close(loadid);
                if (_num == 1) {
                    $(elc).parents(".formControls").find(".form-image-head").attr('src', obj.data[0].url);
                    $(elc).parents(".formControls").find(".iconadd").hide();
                    $(elc).parents(".formControls").find(`[name=${_name}]`).val(obj.data[0].url);
                } else {
                    var _ahtml = "";
                    obj.data.forEach(img => {
                        _ahtml += '<li><img src="' + img.url + '"><i class="Hui-iconfont Hui-iconfont-close2 icon-close"  onclick="handlerRemoveImageItem(this)"></i></li>';
                    });
                    var _imageul = $(elc).parents(".formControls").find(".imageul");
                    $(_imageul).append(_ahtml);
                    //读取所有值到输入框中，作为值
                    handlerReadImages(_name);
                    //超出数量，隐藏添加按钮！
                    if ($(_imageul).find("li").length > _num) {
                        $(_imageul).find("li").eq(0).hide();
                    } else {
                        $(_imageul).find("li").eq(0).show();
                    }
                }
                elc.value = null;
            },
            error: function (res) {
                console.log(res);
                if (loadid != 0) {
                    layer.close(loadid);
                }
                elc.value = null;
                layer.msg(res.statusText, { icon: 'error', time: 3000 });
            }
        });
    } else {
        // layer.msg("请选择至少一个有效的文件！");readmemberToken
    }
}

/**
 * 执行reload判断，判断是否要重新加载页面，需要API配合 还有一个类似的叫changeui
 * @param {*} attributes 
 * @param {*} name 
 * @param {*} val 
 */
function handlerReloadReplace(attributes, name, val) {
    if (attributes) {
        var _attribute = funcFindAttribute(attributes, "reload");
        if (_attribute) {
            if (_attribute.args1) {
                name = _attribute.args1;
            }
            handlerBuildNewUrlToLoad(name, val);
        }
    }
}

/**
 * 执行changeui，是否需要变更ui的显示和隐藏，注意默认值和必填项，如果一个项必填，但是UI隐藏了，那是否还是必填???
 */
function handlerChangeUi(attributes, val) {
    if (attributes) {
        for (let _attribute of attributes) {
            if (_attribute.name == "changeui") {
                handlerChangeUiAttribute(_attribute, val, true);
            }
        }
    }
}

/**
 * 基于changeui特性，进行UI或者数据的变更
 * @param {*} _attribute 
 * @param {*} val 
 * @param {*} isui 是否需要操作ui
 */
function handlerChangeUiAttribute(_attribute, val, isui) {
    // console.log("attribute:",_attribute,"value:",val,'ui:',isui);
    if (_attribute.args1) {
        let match = false;
        if (_attribute.args1.split(',')) {
            for (let _val of _attribute.args1.split(',')) {
                if (_val == val) {
                    match = true;
                    break;
                }
            }
        }
        if (!match) {
            if (_attribute.args2) {
                var strs = _attribute.args2.split(',');
                for (var _str of strs) {
                    if (_str.indexOf("group:") >= 0) {
                        var _gname = _str.substring(6);
                        if (_gname.indexOf("regexp:") >= 0) {
                            let _reg = new RegExp(_gname.substring(7));
                            for (const _gn of _ui_data_list) {
                                if (_gn.isgroup) {
                                    if (_reg.test(_gn.gcode)) {
                                        if (!_gn.hide) {
                                            _gn.hidden = true;
                                        }
                                        if (isui) {
                                            if (!$(`#group_id_${_gn.gcode}`).hasClass("hide")) {
                                                $(`#group_id_${_gn.gcode}`).addClass("hidden").hide();
                                            }
                                        }
                                    }
                                }
                            }
                        } else {
                            for (const _gn of _ui_data_list) {
                                if (_gn.isgroup) {
                                    if (_gn.gcode == _gname) {
                                        if (!_gn.hide) {
                                            _gn.hidden = true;
                                        }
                                        if (isui) {
                                            if (!$(`#group_id_${_gn.gcode}`).hasClass("hide")) {
                                                $(`#group_id_${_gn.gcode}`).addClass("hidden").hide();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        continue;
                    }
                    if (_str.indexOf("regexp:") >= 0) {
                        let _reg = new RegExp(_str.substring(7));
                        for (const _item of _global_data_properties) {
                            if (_reg.test(_item.name)) {
                                if (!_item.hide) {
                                    _item.hidden = true;
                                }
                                if (isui) {
                                    if (!$(`.item_${_item.name}`).hasClass("hide")) {
                                        $(`.item_${_item.name}`).addClass("hidden").hide();
                                    }
                                }
                            }
                        }
                        continue;
                    }
                    for (const _item of _global_data_properties) {
                        if (_item.name == _str) {
                            if (!_item.hide) {
                                _item.hidden = true;
                            }
                            if (isui) {
                                if (!$(`.item_${_item.name}`).hasClass("hide")) {
                                    $(`.item_${_item.name}`).addClass("hidden").hide();
                                }
                            }
                        }
                    }
                }
            }
        } else {
            if (_attribute.args2) {
                var strs = _attribute.args2.split(',');
                for (var _str of strs) {
                    if (_str.indexOf("group:") >= 0) {
                        var _gname = _str.substring(6);
                        if (_gname.indexOf("regexp:") >= 0) {
                            let _reg = new RegExp(_gname.substring(7));
                            for (const _gn of _ui_data_list) {
                                if (_gn.isgroup) {
                                    if (_reg.test(_gn.gcode)) {
                                        if (!_gn.hide) {
                                            _gn.hidden = false;
                                        }
                                        if (isui) {
                                            if (!$(`#group_id_${_gn.gcode}`).hasClass("hide")) {
                                                $(`#group_id_${_gn.gcode}`).removeClass("hidden").show();
                                            }
                                        }
                                    }
                                }
                            }
                        } else {
                            for (const _gn of _ui_data_list) {
                                if (_gn.isgroup) {
                                    if (_gn.gcode == _gname) {
                                        if (!_gn.hide) {
                                            _gn.hidden = false;
                                        }
                                        if (isui) {
                                            if (!$(`#group_id_${_gn.gcode}`).hasClass("hide")) {
                                                $(`#group_id_${_gn.gcode}`).removeClass("hidden").show();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        continue;
                    }
                    if (_str.indexOf("regexp:") >= 0) {
                        let _reg = new RegExp(_str.substring(7));
                        for (const _item of _global_data_properties) {
                            if (_reg.test(_item.name)) {
                                if (!_item.hide) {
                                    _item.hidden = false;
                                }
                                if (isui) {
                                    if (!$(`.item_${_item.name}`).hasClass("hide")) {
                                        $(`.item_${_item.name}`).removeClass("hidden").show();
                                    }
                                    if (_item.dataType == "markdown") {
                                        if (_item.editor) {
                                            _item.editor.resize();
                                        }
                                    }
                                }
                            }
                        }
                        continue;
                    }
                    for (const _item of _global_data_properties) {
                        if (_item.name == _str) {
                            if (!_item.hide) {
                                _item.hidden = false;
                            }
                            if (isui) {
                                if (!$(`.item_${_item.name}`).hasClass("hide")) {
                                    $(`.item_${_item.name}`).removeClass("hidden").show();
                                }
                                if (_item.dataType == "markdown") {
                                    if (_item.editor) {
                                        _item.editor.resize();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

/**
 * 适应reload
 * @param {*} _name 
 * @param {*} _val 
 */
function handlerBuildNewUrlToLoad(_name, _val) {
    // URLSearchParams 这个兼容性
    var _saerch = location.search.substring(1);//当前模式下必然有?path=xxx等
    var argms = _saerch.split('&');
    var argses = new Array();
    for (var _args of argms) {
        if (_args.indexOf(`${_name}=`) == -1) {
            argses.push(_args);
        }
    }
    argses.push(`${_name}=${_val}`);
    //组合query进行reload
    // URLSearchParams.toString
    var _newUrl = `${location.pathname}?${argses.join('&')}`;
    location.replace(_newUrl);
}
/**
 * 判断select是否要执行reload事件
 * @param {*} elc 
 */
function handlerSectionChange(elc) {
    var _name = $(elc).attr("name");
    var _property = funcFindPropertry(_name);
    if (_property) {
        var _val = $(elc).val();
        handlerReloadReplace(_property.attributes, _name, _val);
        handlerChangeUi(_property.attributes, _val);
        // var _attribute = funcFindAttribute(_property.attributes, "reload");
        // if (_attribute) {
        //     var _val = $(elc).val();
        //     if (_attribute.args1) {
        //         _name = _attribute.args1;
        //     }
        //     handlerBuildNewUrlToLoad(_name, _val);
        // }
    }
}

/**
 * 转化数据类型，从数据库的类型转化为UI使用的类型
 * @param {*} properties 
 */
function handlerExchangeDataTypeToUIType(properties) {
    properties.forEach(item => {
        handlerExchangeItemToUIData(item);
        if (_config) {
            if (!_config.dynamic) {
                if (item.name.indexOf("__") >= 0) {
                    _config.dynamic = true;
                }
            }
        }
    });
}

/**
 * 转化数据格式为UI格式
 */
function handlerExchangeItemToUIData(item) {
    item.dataFrom = item.dataType;
    //这里需要处理字段的属性
    if (item.attributes) {
        item.attributes.forEach(_attribute => {
            switch (_attribute.name) {
                case "hidden":
                    {
                        item.hidden = true;
                        if (_attribute.args1) {
                            if (_config.model == _attribute.args1) {
                                item.hidden = false;
                            }
                        }
                    }
                    break;
                case "hide":
                    {
                        item.hide = true;//始终隐藏
                        item.hidden = true;//可以被changeui唤醒
                    }
                    break;
                case "required":
                    {
                        item.required = true;
                    }
                    break;
                case "empty":
                    {
                        item.empty = true;
                    }
                    break;
                case "readonly":
                    {
                        item.readonly = true;
                    }
                    break;
                case "textarea":
                    {
                        item.dataType = "textarea";
                        item.singlerow = true;
                    }
                    break;
                case "cover":
                    {
                        item.dataType = "cover";
                        if (!item.value) {
                            item.value = new Array();
                        } else {
                            if (!Array.isArray(item.value)) {
                                item.value = new Array(item.value);
                            }
                        }
                    }
                    break;
                case "text":
                    {
                        item.dataType = "text";
                        if (item.maxlength) {
                            if (item.maxlength > 64) {
                                item.singlerow = true;
                            }
                        }
                    }
                    break;
                case "fentoyuan":
                    {
                        if (item.value) {
                            item.value = (parseFloat(item.value) / 100).toFixed(2);
                        }
                        item.dataType = "fentoyuan";
                    }
                    break;
                case "file":
                    {
                        item.dataType = 'file';
                        if (_attribute.args1) {
                            item.url = _attribute.args1;
                        }
                        if (_attribute.args2) {
                            item.type = _attribute.args2;
                        }
                        if (_attribute.args3) {
                            item.filehandler = _attribute.args3;
                        }
                        if (!item.url && !item.filehandler) {
                            item.url = "/api/app/Upload/UpFile";
                        }
                    }
                    break;
                case "image":
                    {
                        item.dataType = 'image';
                        if (_attribute.args1) {
                            item.num = parseInt(_attribute.args1);
                        } else {
                            item.num = 1;
                        }
                        if (_attribute.args2) {
                            item.type = _attribute.args2;
                        }
                        if (_attribute.args3) {
                            item.size = _attribute.args3;
                        }
                        if (item.value && item.value != "null") {
                            if (item.num > 1) {
                                if (item.dataFrom == "String[]") {
                                    item.images = item.value;//多个图片是一个数组，字符串数组的形式
                                    item.value = item.value.join(',');
                                } else {
                                    item.images = item.value.split(',');//多个图片之间使用,隔开
                                }
                            }
                        } else {
                            item.value = null;
                        }
                        if (item.num > 1) {
                            item.singlerow = true;
                        }
                    }
                    break;
                case "daterange":
                    {
                        item.dataType = "daterange";
                        if (_attribute.args2) {
                            var _target = funcFindExpendPropertry(_attribute.args2, item.name);
                            if (_target) {
                                _target.hidden = true;
                            }
                        }
                        //2个时间合并到一个去 注意要和js的保持一致 比如yyyy-MM-dd  至  yyyy-MM-dd
                        var _start = "";
                        var _end = "";
                        if (_attribute.args1 == item.name) {
                            _start = item.value;
                        } else {
                            if (_attribute.args1) {
                                var _arg1_obj = funcFindExpendPropertry(_attribute.args2, item.name);
                                if (_arg1_obj) {
                                    if (_arg1_obj.value) {
                                        _start = _arg1_obj.value;//默认为yyyy-MM-dd HH:mm:ss格式
                                        //时间可能是时间戳格式
                                        if (_attribute.args4) {
                                            switch (_attribute.args4) {
                                                case "times":
                                                    {
                                                        _start = new Date(_start * 1000).Format('yyyy-MM-dd HH:mm:ss');
                                                    }
                                                    break;
                                                case "timems":
                                                    {
                                                        _start = new Date(_start * 1000).Format('yyyy-MM-dd HH:mm:ss');
                                                    }
                                                    break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (_start && _attribute.args2) {
                            var _arg2_obj = funcFindExpendPropertry(_attribute.args2, item.name);
                            if (_arg2_obj) {
                                if (_arg2_obj.value) {
                                    _end = _arg2_obj.value;
                                    if (_attribute.args4) {
                                        switch (_attribute.args4) {
                                            case "times":
                                                {
                                                    _end = new Date(_end * 1000).Format('yyyy-MM-dd HH:mm:ss');
                                                }
                                                break;
                                            case "timems":
                                                {
                                                    _end = new Date(_end * 1000).Format('yyyy-MM-dd HH:mm:ss');
                                                }
                                                break;
                                        }
                                    }
                                    var _fulldate = `${new Date(_start).Format('yyyy-MM-dd')}  至  ${new Date(_end).Format('yyyy-MM-dd')}`;
                                    item.value = _fulldate;
                                }
                            }
                        }
                    }
                    break;
                case "datalist":
                    {
                        item.dataType = 'datalist';
                        item.datalistid = item.name;
                        if (_attribute.args1) {
                            try {
                                item.selects = JSON.parse(_attribute.args1);
                            } catch (err) {
                                console.log(item.name, "属性 datalist 的值 args1 配置错误", err);
                            }
                        } else {
                            item.datalistid = _attribute.args2;
                            if (_attribute.args3) {
                                try {
                                    eval(_attribute.args3);
                                } catch (err) {
                                }
                            }
                        }
                    }
                    break;
                case "selects":
                case "select":
                case "lselect":
                    {
                        try {
                            item.dataType = _attribute.name;
                            item.selects = JSON.parse(_attribute.args1);
                            if (item.value || item.value == 0) {
                                var _typeof = typeof (item.value);
                                switch (_typeof) {
                                    case "string":
                                        {
                                            var _splitchar = ',';
                                            if (_attribute.args2) {
                                                _splitchar = _attribute.args2;
                                            }
                                            var strs = item.value.split(_splitchar);
                                            item.selects.forEach(ii => {
                                                if (strs.indexOf(ii.value) >= 0) {
                                                    ii.selected = true;
                                                }
                                            });
                                        }
                                        break;
                                    case "number":
                                        {
                                            var _vals = item.value;
                                            item.selects.forEach(ii => {
                                                if (_vals == (ii.value)) {
                                                    ii.selected = true;
                                                }
                                            });
                                        }
                                        break;
                                    case "object":
                                        {
                                            if (Array.isArray(item.value)) {
                                                // item.selects.forEach(ii => {
                                                //     if (item.value.indexOf(ii.value) >= 0) {
                                                //         ii.selected = true;
                                                //     }
                                                //     // typeof(ii);
                                                // });
                                                for (const ii of item.selects) {
                                                    item.dataFrom = `${typeof (ii.value)}[]`;
                                                    if (item.value.indexOf(ii.value) >= 0) {
                                                        ii.selected = true;
                                                        break;
                                                    }
                                                }
                                            } else {
                                                var _vals = item.value.toString();
                                                // item.selects.forEach(ii => {
                                                //     if (_vals.indexOf(ii.value.toString()) >= 0) {
                                                //         ii.selected = true;
                                                //     }
                                                // });
                                                for (const ii of item.selects) {
                                                    item.dataFrom = `${typeof (ii.value)}[]`;
                                                    if (_vals.indexOf(ii.value.toString()) >= 0) {
                                                        ii.selected = true;
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                        break;
                                }

                            }
                        } catch (err) {
                            console.log(item.name, "属性 select 的值 args1 配置错误", err);
                        }
                    }
                    break;
                case "mark":
                    {
                        var _mark = {
                            model: _classPath,
                            value: item.name
                        };
                        if (_attribute.args1) {
                            _mark.model = _attribute.args1;
                        }
                        if (_attribute.args2) {
                            _mark.value = _attribute.args2;
                        }
                        item.mark = _mark;
                    }
                    break;
                case "style":
                    {
                        item.style = _attribute.args1;
                    }
                    break;
                case "class":
                    {
                        item.class = _attribute.class;
                    }
                    break;
                case "button":
                    {
                        item.dataType = "button";
                        if (!item.buttons) {
                            item.buttons = new Array();
                        }
                        var _btn = ({
                            name: _attribute.args1,
                            func: null
                        });
                        if (_attribute.args1) {
                            _btn.value = _attribute.args1;
                        } else {
                            _btn.value = item.value;
                            _btn.name = item.name;
                        }
                        if (_attribute.args2) {
                            _btn.btnfunc = _attribute.args2;
                        }
                        item.buttons.push(_btn);
                    }
                    break;
                case "score":
                    {
                        item.dataType = "score";
                    }
                    break;
                case "singlerow": {
                    item.singlerow = true;
                }
                    break;
                case "markdown":
                    {
                        item.dataType = "markdown";
                        item.singlerow = true;
                        _global_need_loadmarkdown = true;
                        if (_attribute.args2) {
                            var _target = funcFindExpendPropertry(_attribute.args2, item.name);
                            if (_target) {
                                _target.hidden = true;
                            }
                        }
                    }
                    break;
                case "richtext":
                    {
                        item.dataType = "richtext";
                        item.singlerow = true;
                        _global_need_loadrichhtml = true;
                    }
                    break;
                case "unit":
                    {
                        item.unit = _attribute.args1;
                    }
                    break;
                case "object":
                    {
                        item.dataType = 'object';
                        item.session_key = `${item.name}_0000`;
                        if (item.value) {
                            sessionStorage.setItem(item.session_key, JSON.stringify(item.value));
                            //UI上如何显示
                            if (_attribute.args4) {
                                if (item.value.hasOwnProperty(_attribute.args4)) {
                                    item.display = item.value[_attribute.args4];
                                }
                            }
                        } else {
                            sessionStorage.removeItem(item.session_key);
                        }
                        if (!item.hidden) {
                            _has_outer = true;
                        }
                    }
                    break;
                case "objects":
                    {
                        item.dataType = 'objects';
                        if (item.value) {
                            item.objects = item.value;

                        }
                        if (_attribute.args3) {
                            item.display_id = _attribute.args3;
                        } else {
                            item.display_id = "id";
                        }
                        if (_attribute.args4) {
                            item.display_name = _attribute.args4;
                        } else {
                            item.display_name = "name";
                        }
                        if (item.objects) {
                            var _list = new Array();
                            item.objects.forEach(_item => {
                                _item._id = handlerColumnValue(_item, item.display_id);
                                _item._display = handlerColumnValue(_item, item.display_name);
                                _list.push(_item);
                            });
                            _map_values.set(item.name, _list);
                        }
                        _has_outer = true;
                    }
                    break;
                case "outer":
                    {
                        item.dataType = 'outer';
                        let _set_value = true;
                        if (_attribute.args2) {
                            var _target = funcFindExpendPropertry(_attribute.args2, item.name);
                            if (_target) {
                                _target.hidden = true;
                                if (_target.value) {
                                    if (typeof _target.value == "object") {
                                        if (_attribute.args4) {
                                            // item.display = _target.value[_attribute.args4];
                                            item.display = handlerColumnValue(_target.value, _attribute.args4);// _target.value[_attribute.args4];
                                            _set_value = false;
                                        }
                                    }
                                }
                            }
                        }
                        if (_set_value) {
                            if (item.value) {
                                item.display = item.value;
                            }
                        }
                        _has_outer = true;
                    }
                    break;
                case "outers":
                    {
                        item.dataType = 'outers';
                        if (_attribute.args2) {
                            var _target = funcFindExpendPropertry(_attribute.args2, item.name);
                            if (_target) {
                                _target.hidden = true;
                                if (_target.value && _target.value != '') {
                                    item.display = _target.value;
                                    item.display.forEach(_dis => {
                                        _dis._display = handlerColumnValue(_dis, _attribute.args4);
                                    });
                                }
                            }
                        }
                        item.display_id = _attribute.args3;
                        item.display_name = _attribute.args4;
                        _has_outer = true;
                    }
                    break;
                case "splitarray":
                    {
                        item.dataType = "splitarray";
                        if (item.value) {
                            if (_attribute.args1) {
                                item.value = item.value.join(_attribute.args1);//用其他字符分割
                            } else {
                                item.value = item.value.toString();//使用,分割
                            }
                        } else {
                            item.value = "";
                        }
                    }
                    break;
                case "datetime":
                    {
                        item.dataType = "datetime";
                        var _format = "yyyy-MM-dd HH:mm:ss";
                        if (_attribute.args1) {
                            _format = _attribute.args1;
                        }
                        item.format = _format;
                        if (item.value) {
                            if (_attribute.args2) {
                                switch (_attribute.args2) {
                                    case "times":
                                        {
                                            item.value = new Date(item.value * 1000).Format(_format);
                                        }
                                        break;
                                    case "timems":
                                        {
                                            item.value = new Date(item.value).Format(_format);
                                        }
                                        break;
                                    default:
                                        {
                                            item.value = new Date(item.value).Format(_format);
                                        }
                                        break;
                                }
                            }
                        }
                    }
                    break;
                case "point":
                    {
                        item.point = true;
                    }
                    break;
                case "sunform":
                    {
                        item.dataType = "sunform";
                        item.singlerow = true;
                        item.frame = {
                            height: 300,
                            url: "",
                            class: ""
                        };
                        var session_key = `${item.name}_00000`;
                        if (item.value) {
                            sessionStorage.setItem(session_key, JSON.stringify(item.value));
                        } else {
                            sessionStorage.removeItem(session_key);
                        }
                        if (_attribute.args3) {
                            item.frame.class = _attribute.args3;
                        }
                        //model=sunobj
                        var _tar_url = handlerBuildDynamicUrl(_attribute.args1);
                        if (_tar_url.indexOf('/') >= 0) {
                            if (_tar_url.indexOf("?") >= 0) {
                                item.frame.url = _tar_url + '&session_key=' + session_key;
                            } else {
                                item.frame.url = _tar_url + '?session_key=' + session_key;
                            }
                        } else {
                            item.frame.url = `${handlerPasteFormPath()}view.html?path=${_tar_url}&model=sunobj&session_key=${session_key}`;
                        }
                        if (_attribute.args2) {
                            item.frame.height = _attribute.args2;
                        }
                    }
                    break;
                case "notice":
                case "password":
                    {
                        item.dataType = _attribute.name;
                    }
                    break;
                case "changeui":
                    {
                        if (_changeui_list) {
                            _changeui_list.push({
                                attribute: _attribute,
                                value: item.value
                            });
                        }
                    }
                    break;
                default:
                    break;
            }
        });
    }

    //如果是故意要暴露id的呢？
    if (item.name == "id") {
        if (!item.placeholder) {
            item.hidden = true;
        }
        //编辑模式必须隐藏，防止修改到其他信息去
        if (_config.model == 'edit') {
            item.hidden = true;
        }
        //所以如果id需要自定义的需要特别备注比如 ID 可填可不填
    }

    //Guid的默认处理
    if (item.dataFrom == "Guid") {
        if (item.value == "00000000-0000-0000-0000-000000000000") {
            item.value = "";
            if (item.display == "00000000-0000-0000-0000-000000000000") {
                item.display = "";
            }
        }
    }

    switch (item.dataType) {
        case "Int32":
        case "Int64":
            {
                item.dataType = "number";
                if (item.value == "0") {
                    item.value = "";
                }
            }
            break;
        case "DateTime":
            {
                item.dataType = "datetime";
                if (item.value && item.value == '01/01/0001 00:00:00') {
                    item.value = "";
                }
                if (!item.format) {
                    item.format = "yyyy-MM-dd HH:mm:ss";
                }
            }
            break;
        case "Boolean":
            {
                item.dataType = "switch";
            }
            break;
        case "Double":
        case "Decimal":
            {
                item.step = "0.01";
                if (item.attributes) {
                    item.attributes.forEach(_attribute => {
                        if (_attribute.name == 'double') {
                            item.step = _attribute.args1;
                        }
                    });
                }
            }
            break;
        case "String":
            {
                if (item.value == null) {
                    item.value = "";
                }
                if (item.maxlength == 0) {
                    item.dataType = "richtext";
                    item.singlerow = true;
                    _global_need_loadrichhtml = true;
                }
                if (item.maxlength > 128) {
                    item.dataType = "textarea";
                    item.singlerow = true;
                }
                if (item.maxlength <= 128 && item.maxlength != 0) {
                    item.dataType = "text";
                    if (item.maxlength > 64) {
                        item.singlerow = true;
                    }
                }
            }
            break;
    }

    if (item.hidden) {
        if (item.required) {
            item.required = false;
        }
    }
    if (item.required) {
        if (item.point) {
            item.point = false;
        }
    }
}

/**
 * 查找组信息 并添加到数据集合 或者是添加子项
 * @param {*} _group_name 
 * @param {*} _ui_data_list 
 * @returns 
 */
function handlerTakeGroupInfo(_group_name, _ui_data_list, item) {
    var _handler = false;
    if (_ui_data_list) {
        for (var ii of _ui_data_list) {
            if (ii.isgroup) {
                if (ii.gcode == _group_name) {
                    ii.groups.push(item);
                    _handler = true;
                    break;
                }
            }
        }
    }

    if (_global_class_attributes && !_handler) {
        for (var ii of _global_class_attributes) {
            if (ii.name == "group") {
                if (ii.args1 == _group_name) {
                    var _info = {
                        isgroup: true,
                        singlerow: true,
                        gcode: _group_name,
                        gname: ii.args2,
                        isopen: (ii.args3 != 'close'),
                        groups: new Array(),
                        hidden: false
                    };
                    if (_info.isopen) {
                        _info.gclass = "open";
                    } else {
                        _info.gclass = "close";
                    }
                    if (ii.args4) {
                        _info.gmodel = 'edit';
                    }
                    if (ii.args3 == 'hidden') {
                        _info.hidden = true;
                    }
                    _handler = true;
                    _info.groups.push(item);
                    _ui_data_list.push(_info);
                    break;
                }
            }
        }
    }
    //如果没有找到，是否基于当前New一个
    if (!_handler) {
        var ii = funcFindAttribute(item.attributes, "group");
        if (ii) {
            var _info = {
                isgroup: true,
                singlerow: true,
                gcode: _group_name,
                gname: ii.args2,
                isopen: (ii.args3 != 'close'),
                groups: new Array(),
                hidden: false
            };
            if (_info.isopen) {
                _info.gclass = "open";
            } else {
                _info.gclass = "close";
            }
            if (ii.args4) {
                _info.gmodel = 'edit';
            }
            if (ii.args3 == 'hidden') {
                _info.hidden = true;
            }
            _handler = true;
            _info.groups.push(item);
            _ui_data_list.push(_info);
        }
    }
    return null;
}

/**
 * 更换UI的某一块
 * @param {*} item 
 */
function handler_replace_item(item) {
    handlerExchangeItemToUIData(item);
    var _name = item.name;
    var _theml = $("#template_tr_item").html();
    var _vhtml = template(_theml, { item: item });
    if ($(`.item_${_name}`).length > 0) {
        $(`.item_${_name}`).replaceWith(_vhtml);
    } else {
        $(".paste-form-body").append(_vhtml);
    }
}